/*
 * myqueue.cpp
 *
 *  Created on: Jan 18, 2014
 *      Author: yosef
 */


#include <stdio.h>
#include <stdlib.h>
#include "myqueue.h"


int MyOwnQueue::Create(unsigned int QueueLength, unsigned int QueueSize)
{
	queuesegment = malloc(QueueLength * QueueSize);
	if(!queuesegment) return -1;

	tail = 0;
	size = QueueSize;
	avil_space = QueueLength;

	return 0;
}


int MyOwnQueue::Send(const void *QueueItem)
{
	if(!queuesegment) return -1;
	if (!avil_space) return -2;
	if (!QueueItem) return -3;

	// Copy item onto queue space
	switch(size)
	{
		case 1:
			*((unsigned char *)queuesegment + tail) = *(unsigned char *)QueueItem;
		break;

		case 2:
			*((unsigned short int *)queuesegment + tail) = *(unsigned short int *)QueueItem;
		break;

		case 4:
			*((unsigned long int *)queuesegment + tail) = *(unsigned long int *)QueueItem;
		break;

		case 8:
			*((double *)queuesegment + tail) = *(double *)QueueItem;
		break;

		default:
			return -4;

	}

	tail++;
	avil_space--;

	return 0;
}


int MyOwnQueue::Receive(void *QueueItem)
{
	unsigned int i;

	if(!queuesegment) return -1;
	if (!QueueItem) return -2;
	if(tail == 0) return -3;

	switch(size)
	{
		case 1:
			*(unsigned char *)QueueItem =  *(unsigned char *)queuesegment;
			for(i = 0; i < tail - 1; i++)
				*((unsigned char *)queuesegment + i) = *((unsigned char *)queuesegment + i + 1);
			*((unsigned char *)queuesegment + i) = 0;
		break;

		case 2:
			*(unsigned short int *)QueueItem =  *(unsigned short int *)queuesegment;
			for(i = 0; i < tail - 1; i++)
				*((unsigned short int *)queuesegment + i) = *((unsigned short int *)queuesegment + i + 1);
			*((unsigned short int *)queuesegment + i) = 0;
		break;

		case 4:
			*(unsigned long int *)QueueItem =  *(unsigned long int *)queuesegment;
			for(i = 0; i < tail - 1; i++)
				*((unsigned long int *)queuesegment + i) = *((unsigned long int *)queuesegment + i + 1);
			*((unsigned long int *)queuesegment + i) = 0;
		break;

		case 8:
			*(double *)QueueItem =  *(double *)queuesegment;
			for(i = 0; i < tail - 1; i++)
				*((double *)queuesegment + i) = *((double *)queuesegment + i + 1);
			*((double *)queuesegment + i) = 0;
		break;

		default:
			return -4;

	}

	avil_space++;
	tail--;

	return 0;
}


void MyOwnQueue::Delete(void)
{
	free(queuesegment);
}

